require"lfs"
BASE = "e:\\videos"
DEST = "z:\\"
SEP = "\\"
LOG = DEST.."shows.log"
SUPPORTED_EXTENSIONS = {
	avi = true,
	mkv = true,
}

TVRAGE_URL_BASE = "http://www.tvrage.com/quickinfo.php?show=%s&ep=%dx%d"

function get(url)
	print("GET", url)
	local tmp = os.tmpname()
	os.execute(string.format("c:\\Tools\\wget -q -O \"%s\" \"%s\"", tmp, url))
	
	local f = io.open(tmp, "r")
	local data = f:read("*a")
	f:close()
	os.remove(tmp)
	
	return data
end

local function cleanup(s)
	return s:gsub("%?", ""):gsub(":", ""):gsub("/", " "):gsub("\\", "_"):gsub("%*", "_")
end

local function append_tvrage_line(line, result)
	local p = line:find("@", nil, true)
	if not p then return end
	local key = line:sub(1, p - 1)
	local value = line:sub(p + 1)
	if value:find("^", nil, true) then
		local s, p = value, 1
		value = {}
		while true do
			local i = s:find("^", p, true)
			if not i then
				value[#value + 1] = s:sub(p)
				break
			end
			value[#value + 1] = s:sub(p, i - 1)
			p = i + 1
		end
	end
	assert(not result[key])
	result[key] = value
end

local function get_row_tvrage_data(s)
	local result = {}
	local p = 1
	while true do
		local i, j = s:find("[\r\n]+", p)
		if not i then
			append_tvrage_line(s:sub(p), result)
			return result
		end
		append_tvrage_line(s:sub(p, i - 1), result)
		p = j + 1
	end
end

local function clean_url_showname(src)
	return src:gsub("^.*[\\/]", ""):gsub("[%. ]*$", ""):gsub("[%. ]", "+")
end

local function makesubdirs(s)
	local path
	for k in s:gmatch("(.-)"..SEP) do
		if not path then
			path = k
		else
			path = path .. SEP .. k
		end
		local attr = lfs.attributes(path)
		if not attr and not path:match("^[a-zA-Z]:$") then
			print("creating", path)
			lfs.mkdir(path)
			attr = lfs.attributes(path)
		end
		assert(path:match("^[a-zA-Z]:$") or (attr and attr.mode == "directory"))
	end
end

local function get_better_filename(src)
	local base = src:match("(.*[\\/])") or ""
	local ext = src:match("(%.[^.]+)$")
	local i, j, season, episode = src:find("[Ss](%d+)[Ee](%d+)")
	if not i then
		i, j, season, episode = src:find("(%d+)[Xx](%d+)")
	end
	
	assert(i)
	season = assert(tonumber(season))
	episode = assert(tonumber(episode))
	
	local url = TVRAGE_URL_BASE:format(clean_url_showname(src:sub(1, i - 1)),
		tonumber(season), tonumber(episode))

	local data = get_row_tvrage_data(get(url))

	local show = cleanup(data["Show Name"])
	local season_name = ("Season %d"):format(season)
	local episode_name = ("%s - %dx%2.2d - %s"):format(show, season, episode, cleanup(data["Episode Info"][2]))
	
	return DEST..show..SEP..season_name..SEP..episode_name..ext
end

for file in lfs.dir(BASE) do
	local ext = file:match("%.([^.]*)$")
	if ext and SUPPORTED_EXTENSIONS[ext] then
		local src = BASE..SEP..file
		local status, dst = pcall(get_better_filename, src)
		if status then
			print(dst)
			makesubdirs(dst)
			if lfs.attributes(dst) then
				if src:lower():find("proper") then
					print("REPLACE", dst)
					os.remove(dst)
				end
			end
			local status, message = os.rename(src, dst)
			if not status then
				print("ERROR", message)
			else
				local f = io.open(LOG, "a")
				f:write(dst, "\n")
				f:close()
			end
		end
	end
end
print("DONE, press a key to continue...")
io.read()
